package solutions;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.pi4.locutil.GeoPosition;
import org.pi4.locutil.Statistics;
import org.pi4.locutil.io.TraceGenerator;
import org.pi4.locutil.trace.Parser;
import org.pi4.locutil.trace.TraceEntry;

import solutions.MainAlgorithmRunner.TraceEstimater;

public class PlottingTwoBasedKManAlg {
	static final int offlineSize = 25;
	static final int onlineSize = 5;

	public static void main(String[] args) throws Exception {

		Parser offlineParser = new Parser(new File(
				"data/MU.1.5meters.offline.trace"));
		Parser onlineParser = new Parser(new File(
				"data/MU.1.5meters.online.trace"));

		TraceGenerator tg = new TraceGenerator(offlineParser, onlineParser,
				offlineSize, onlineSize);
		tg.generate();
		List<TraceEntry> apPosition = WifiPositionsParser
				.parser("data/MU.AP.positions");
		BufferedWriter writer = new BufferedWriter(new FileWriter(new File(
				"PlottingTwoBasedKManAlg")));
		writer.write("# \t k \t \t med acc \n");
		for (int i = 1; i < 6; i++) {
			writer.write("" + i + "\t");
			double value = calculate(i, new ModelKNN(tg, null, i, apPosition),
					tg, writer);
			writer.write(value + "\t");
			value = calculate(i, new FingerPrintingKNN(tg, null, i), tg, writer);
			writer.write(value + "\t");
			writer.write("\n");
		}
		writer.close();
	}

	public static double calculate(int k, TraceEstimater estimater,
			TraceGenerator tg, BufferedWriter writer) throws IOException {

		List<TraceEntry> onlineTrace = tg.getOnline();
		estimater.buildRadioMap(tg.getOffline());
		List<Double> distancesMedian = new ArrayList<Double>(100);
		List<Double> distancesAverage = new ArrayList<Double>(100);

		for (int i = 0; i < 100; i++) {
			tg.generate();
			for (TraceEntry entry : onlineTrace) {
				GeoPosition estimatePos = estimater.estimatePosition(entry);
				distancesMedian.add(PositionUtils.getDistance(estimatePos,
						entry.getGeoPosition()));

			}
			distancesAverage.add(Statistics.median(distancesMedian));
		}

		return Statistics.avg(distancesAverage);
	}
}
